(defmacro make-symbol-name (obj &optional (format-string "~a"))
  "Make a name for the symbol from a <_:arg format-string /> and some <_:arg obj />ect, which can be used e.g. to <_:fun defun /> (works on the basis of <_:fun format />)"
  `(read-from-string (format nil ,format-string ,obj)))


(defparameter *pos* 0)
(defparameter *instructions* nil)

(defmacro def-instr (name (&rest args) &rest instr-body)
  `(defmacro ,(make-symbol-name name "ant-~a") (,@args &body body)
     (progn ,@instr-body)))

(defun save (instr)
  (setf *instructions* (append *instructions* (list instr))))


; instrs

(def-instr loop ()
  `(let ((start *pos*))
     ,@body
     (ant-goto start)))

(def-instr goto (pos)
  `(op-flip 1 ,pos 0))

(def-instr move-dir (dir)


; ops

(defmacro def-op (name &rest args)
  `(defun ,(make-symbol-name name "op-~a") (,@args)
     (save (list ',name ,@args))
     (incf *pos*)))

(def-op flip rand st1 st2)

(def-op sense sensedir st1 st2 cond)

(def-op mark i st)

(def-op unmark i st)

(def-op pickup st1 st2)

(def-op drop st)

(def-op turn lr st)

(def-op move st1 st2)